﻿Imports Kent.Boogaart.KBCsv
Imports System.Linq

Public Class rankingDataTable

    Inherits DataTable

    ''' <summary>
    ''' indentify where we loaded the ranks from (local file / web)
    ''' </summary>
    Public Enum Loadedfrom
        none = 0
        web = 1
        file = 2
    End Enum


    Private mloadedfrom As Loadedfrom = Loadedfrom.none
    Dim doc As HtmlAgilityPack.HtmlDocument
    Dim testform As New Form3
    Private wclient As New System.Net.WebClient
    Private popthrd As Threading.Thread

    Private mtablepopulating As Boolean = False
    Private mIspageloading As Boolean = False
    Private mProcessed As Boolean = False
    Private mStartpage As Decimal = 0
    Private mEndpage As Decimal = 0

    Public Event loadingfinshed()
    Public Event downloadingnewpage(page As Decimal)

    ''' <summary>
    ''' Setup the datatable with the columns and their names
    ''' </summary>
    Public Sub setupDataTable()

        MyBase.Columns.Add("Position", GetType(Int32))
        MyBase.Columns.Add("Name")
        MyBase.Columns.Add("ID")
        MyBase.Columns.Add("Rank")
        MyBase.Columns.Add("Prestige")
        MyBase.Columns.Add("Additional info")
    End Sub

    ''' <summary>
    ''' Load a CSV file into our new datatable (CSVFileName = full path+filename)
    ''' </summary>
    Public Sub loadCSVFileIntoTable(ByVal CSVFileName As String)
        Dim reader As CsvReader
        Dim dataset As DataSet = Nothing

        Try

            reader = New CsvReader(CSVFileName)
            reader.ReadHeaderRecord()
            dataset = New DataSet
            reader.Fill(dataset, "temp")

        Finally
            If (Not reader Is Nothing) Then
                reader.Close()
            End If

            MyBase.Merge(dataset.Tables("temp"))

        End Try
        mloadedfrom = Loadedfrom.file
    End Sub

    ''' <summary>
    ''' Save the contents of our table to a CSV file on the users local machine
    ''' </summary>
    Public Sub saveTableToCSVFile(ByVal CSVFileName As String)
        Dim tempDT As DataTable = New DataTable
        Dim writer As CsvWriter = Nothing

        tempDT = MyBase.Copy
        Try
            writer = New CsvWriter(CSVFileName)
            writer.WriteAll(tempDT, True)
        Finally
            If (Not writer Is Nothing) Then
                writer.Close()
            End If
        End Try
    End Sub

    ''' <summary>
    ''' Retrieve the ranks from the online DS site and load them in our table
    ''' </summary>
    Public Sub loadrankingpagesfromweb(ByVal startpage As Integer, ByVal endpage As Integer)

        setupDataTable()
        mStartpage = startpage
        mEndpage = endpage

        process(Me, Nothing)

        mloadedfrom = Loadedfrom.web
    End Sub
    Private Sub process(ByVal sender As Object, ByVal e As Net.DownloadStringCompletedEventArgs)
        ' popthrd = New Threading.Thread(AddressOf populateDataTable)
        'popthrd.IsBackground = True

        'While mtablepopulating = True
        Threading.Thread.Sleep(100)
        'End While

        If sender Is wclient Then

            populateDataTable(e.Result)
            ' popthrd.Start(e.Result)
        ElseIf sender Is Me Then

            While wclient.IsBusy = True
                Threading.Thread.Sleep(100)
            End While

            If mStartpage <= mEndpage Then

                Dim offset As Decimal = 0
                If mStartpage - 1 = 0 Then
                    offset = 0
                Else
                    offset = (mStartpage - 1) * 100
                End If

                loadPagefromweb(offset)
            Else
                RaiseEvent loadingfinshed()
                '[Select]("Position < 5000", "Position DESC")
            End If

        End If

    End Sub


    '''<summary>
    ''' Load a single ranking page from the darkspace website
    '''</summary>
    Private Sub loadPagefromweb(ByVal pagenumber As Decimal)

        wclient = New System.Net.WebClient


        'Dim source As String = wclient.DownloadString("http://darkspace.net/index.htm?module=ranking.php&offset=" + pagenumber.ToString + "&field_id=0")
        'doc = New HtmlAgilityPack.HtmlDocument
        wclient.DownloadStringAsync(New Uri("http://darkspace.net/index.htm?module=ranking.php&offset=" + pagenumber.ToString + "&field_id=0"))
        'doc.LoadHtml(wclient.)
        AddHandler wclient.DownloadStringCompleted, AddressOf process
        RaiseEvent downloadingnewpage(mStartpage)

        ' Dim web As HtmlAgilityPack.HtmlWeb = New HtmlAgilityPack.HtmlWeb

        'doc.LoadHtml(source)

    End Sub

    ''' <summary>
    ''' Retrieve the links from the ranking table off the HTML page and strip it from its information and add it to the Datatable
    ''' </summary>
    Private Sub populateDataTable(ByVal source As String)
        mtablepopulating = True
        doc = New HtmlAgilityPack.HtmlDocument
        doc.LoadHtml(source)

        ' below we select all tablerows from the 2nd position and higher in our html document,
        ' inside a nested table table with class name 'std_test' inshtml ide a table with the same class name
        '"//table[@class='std_text']//table[@class='std_text']/tr[position() >= 2]  "
        For Each link As HtmlAgilityPack.HtmlNode In doc.DocumentNode.SelectNodes("//tr/td[@bgcolor='#101414' or @bgcolor='#1D2323' ]/..")
            'testform.TextBox2.AppendText(link.InnerHtml.ToString & "@" & vbCrLf)
            Rows.Add(link.ChildNodes(1).InnerHtml, link.ChildNodes(3).InnerText, extractIDfromURL(link.ChildNodes(3).InnerHtml), link.ChildNodes(5).InnerText, link.ChildNodes(7).InnerText)
            Application.DoEvents()
        Next
        mtablepopulating = False
        mStartpage += 1
        process(Me, Nothing)
    End Sub

    ''' <summary>
    ''' Extract the ID from the URL on the html page and return that as a string
    ''' </summary>
    Private Function extractIDfromURL(ByVal URL As String) As String
        Dim lastApo As Integer
        Dim secondIs As Integer


        Dim returnVal As String = String.Empty
        Dim collection As System.Text.RegularExpressions.MatchCollection = System.Text.RegularExpressions.Regex.Matches(URL, "\d+")

        For Each m As System.Text.RegularExpressions.Match In collection
            returnVal += m.ToString()
        Next

        secondIs = URL.LastIndexOf("php&view=")
        lastApo = URL.LastIndexOf(Chr(34))

        Return URL.Substring(secondIs + 9, lastApo - secondIs - 9)

    End Function

    ''' <summary>
    ''' Returns a loadedfrom enum specifying where the table was loaded from web or local file
    ''' </summary>
    ReadOnly Property IsLoadFrom() As Loadedfrom
        Get
            Return mloadedfrom
        End Get
    End Property
    ''' <summary>
    ''' Returns a datatable (result_DT) containing the results from the search query
    ''' </summary>
    Public Function searchInDatatable(ByRef Search_DT As DataTable, ByRef Result_DT As DataTable, ByVal fieldname As String, ByVal searchstring As String, ByVal sortascending As Boolean) As Integer
        searchInDatatable = False

        Dim resultrows = From resulting_rows In Search_DT.AsEnumerable Where resulting_rows.Field(Of String)(fieldname).ToLower.Contains(searchstring.ToLower) Select resulting_rows

        Result_DT = New DataTable
        Result_DT = Search_DT.Clone

        If sortascending Then

            Dim sortedrows = From unsortedrows In resultrows Order By unsortedrows!Position Ascending

            If sortedrows.Count > 0 Then
                Result_DT = sortedrows.CopyToDataTable
                searchInDatatable = True
            Else
                MsgBox("The " & searchstring & " you're trying to find is not found in current ranks" & vbCrLf & _
                        "Please try again with a different ID" & searchstring, , _
                        searchstring & " not found")
            End If

        Else
            If resultrows.Count > 0 Then
                Result_DT = resultrows.CopyToDataTable
                searchInDatatable = True
            Else
                MsgBox("The " & searchstring & " you're trying to find is not found in current ranks" & vbCrLf & _
                        "Please try again with a different ID" & searchstring, , _
                        searchstring & " not found")
            End If


        End If

    End Function
End Class
